package com.chinareny2k.commons.excel.handler;

import com.chinareny2k.commons.excel.ExcelTemplateHandler;
import com.chinareny2k.commons.excel.annotation.ExcelTemplateValidationField;
import com.chinareny2k.commons.excel.annotation.Template;
import com.chinareny2k.commons.excel.support.ExcelTemplate;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.util.IOUtils;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ExcelAnnotationTemplateHandler<T extends ExcelTemplate> implements ExcelTemplateHandler {

    private T template;
    private Integer MAX_ROW_NUM = 65535;

    ExcelAnnotationTemplateHandler(T template ){
        this.template = template;
    }

    @Override
    public void  exportTemplate(InputStream in, OutputStream out) throws Exception {
        Template templateAnnotation = this.template.getClass().getAnnotation(Template.class);
        if(templateAnnotation == null){
            IOUtils.copy(in, out);
            return;
        }
        ExcelTemplateValidationField[] fields = templateAnnotation.value();

        Workbook workbook = WorkbookFactory.create(in);
        Sheet workSheet = workbook.getSheetAt(templateAnnotation.sheetIndex());
        DataValidationHelper helper = workSheet.getDataValidationHelper();
        Arrays.stream(fields).forEach(field->{
            createValidationField(workbook,field,size->{
                DVConstraint.createFormulaListConstraint(field.sheetName() + "!$A$1:$A$" + size);
                DataValidationConstraint constraint = helper.createFormulaListConstraint(field.sheetName() + "!$A$1:$A$" + size);
                CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(field.firstRow(), MAX_ROW_NUM, field.column(), field.column());
                DataValidation validation = helper.createValidation(constraint, cellRangeAddressList);
                if(validation instanceof HSSFDataValidation){
                    validation.setSuppressDropDownArrow(false);
                }else{
                    validation.setSuppressDropDownArrow(true);
                    validation.setShowErrorBox(true);
                }
                workSheet.addValidationData(validation);
            });
        });
        workbook.write(out);
    }

    private void createValidationField(Workbook workbook, ExcelTemplateValidationField field, Consumer<Integer> consumer ) {
        Sheet hiddenSheet = workbook.createSheet(field.sheetName());
        List<String> values = template.getParam(field.sheetName());
        for(int i = 0;i < values.size();i++){
            Row row = hiddenSheet.createRow(i);
            Cell cell = row.createCell(0);
            cell.setCellValue(values.get(i));
        }
        workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true);
        consumer.accept(values.size());

    }

}
